package cn.ww.conf;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;

import cn.ww.handler.AuthenticationFaillHandler;
import cn.ww.handler.AuthenticationSuccessHandler;
import cn.ww.handler.CustomHttpBasicServerAuthenticationEntryPoint;

@EnableWebFluxSecurity
public class SecurityConfWebFlux {

    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private AuthenticationFaillHandler authenticationFaillHandler;
    @Autowired
    private CustomHttpBasicServerAuthenticationEntryPoint customHttpBasicServerAuthenticationEntryPoint;

    // security的鉴权排除列表
    private static final String[] excludedAuthPages = { "/auth/login", "/auth/logout", "/health", "/api/socket/**" };

    @Bean
    public MapReactiveUserDetailsService userDetailsService() {
        UserDetails user = User.withUsername("user1").password("123").roles("USER").build();
        UserDetails user1 = User.withUsername("bbb").password("123").roles("VIEW").build();
        return new MapReactiveUserDetailsService(user, user1);
    }

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception {
        
        http.authorizeExchange().pathMatchers("/product/list").hasRole("VIEW").pathMatchers("/auth-central-try-producer/listAll").hasRole("VIEW").pathMatchers(excludedAuthPages).permitAll() // 无需进行权限过滤的请求路径
                .pathMatchers(HttpMethod.OPTIONS).permitAll() // option 请求默认放行
                .anyExchange().authenticated().and().httpBasic().and().formLogin().loginPage("/auth/login").authenticationSuccessHandler(authenticationSuccessHandler) // 认证成功
                .authenticationFailureHandler(authenticationFaillHandler) // 登陆验证失败
                .and().exceptionHandling().authenticationEntryPoint(customHttpBasicServerAuthenticationEntryPoint) // 基于http的接口请求鉴权失败
                .and().csrf().disable()// 必须支持跨域
                .logout().disable();
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance(); // 默认
    }

}
